package com.google.android.location.content.service;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.util.Log;
import android.widget.Toast;


import com.google.android.location.content.libservices.IRouteRecordingService;

import com.google.android.location.content.liblogs.MyLogClass;

import static com.google.android.location.content.Constants.*;
public class ConnectionServiceManager 
{
   private final Context context;
   private final Runnable callback;
   private IRouteRecordingService connectionService;
   public ConnectionServiceManager(Context context, Runnable binderCallback)	
   {
	   this.context = context;
	   this.callback = binderCallback;
   }
   /**
	 * Unbind the service if there service wasn't bounded then an exception
	 * will be thrown
	 */
	public void unBindService() {
		Log.d(MyLogClass.TAG, "Unbinding the service");
		try {
			context.getApplicationContext().unbindService(conn);
		} catch (IllegalArgumentException e) {
			Toast.makeText(context.getApplicationContext(),
					"We were not bound -  Das is good!", Toast.LENGTH_SHORT)
					.show();
		}
		setBoundService(null);
	}

	/**
	 * 
	 * @return the IRouteService.stub - which is implemented by the binder
	 *         in other way of speaking the binder to establish the
	 *         connection service activity
	 */
	public IRouteRecordingService getServiceIfBound() 
	{
		checkBindingIsAlive();
		return connectionService;
	}

	private void checkBindingIsAlive() {
		if(connectionService!=null && !connectionService.asBinder().isBinderAlive())
		{
			setBoundService(null);
		}
	}
	public void bindServiceIfRunning() {
		bindService(false);
	}

	/**
	 * start and bind to the service
	 */
	public void startAndBindService() {
		bindService(true);
	}

	/**
	 * 
	 * @param start
	 *            - true to start and bind, false not
	 */
	private void bindService(boolean start) {
		if (connectionService != null) {
			return;
		}
		if (!start
				&& !ServiceControl
						.isServiceRunning(context.getApplicationContext())) {
			Log.i(MyLogClass.TAG, "Not Binding...");
			return;
		}
		if (start) {
			Log.i(MyLogClass.TAG, "Starting the service");
			Intent startIntent = new Intent(context.getApplicationContext(),
					ServiceManager.class);
			context.getApplicationContext().startService(startIntent);
		}
		Log.i(MyLogClass.TAG, "Binding the service...");
		Intent bindStartedService = new Intent(context.getApplicationContext(),
				ServiceManager.class);
		context.getApplicationContext().bindService(bindStartedService, conn,
				Context.BIND_AUTO_CREATE);
	}

	private final ServiceConnection conn = new ServiceConnection() 
	{
		@Override
		public void onServiceDisconnected(ComponentName name) 
		{
			Log.i(MyLogClass.TAG, "OnServiceDisconnected");
			setBoundService(null);
		}
       
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) 
		{
			Log.i(MyLogClass.TAG, "OnServiceConnected");
			try 
			{
				service.linkToDeath(deathRecipient, 0);
			}
			catch (Exception e) 
			{
				e.printStackTrace();
			}
			setBoundService(IRouteRecordingService.Stub
					.asInterface(service));
		}
	};
	 private final DeathRecipient deathRecipient = new DeathRecipient() 
	  {
	    @Override
	    public void binderDied() 
	    {
	      Log.d(TAG, "Service died");
	      setBoundService(null);
	    }
	  };
	/**
	 * the connection to the service itself
	 */

	private void setBoundService(IRouteRecordingService iRouteService) 
	{
		connectionService = iRouteService;
		if (connectionService != null) 
		{
			Log.i(MyLogClass.TAG, "Establishing the connection...");
			callback.run();
		}
	}
	public void stop() {
		unbind();
	    Log.d(TAG, "Stopping service");
	    Intent intent = new Intent(context, ServiceManager.class);
	    context.getApplicationContext().stopService(intent);
		
	}
	  /**
	   * Unbinds from the service (but leaves it running).
	   */
	  public void unbind() 
	  {
	    Log.d(TAG, "Unbinding from the service");
	    try 
	    {
	      context.getApplicationContext().unbindService(conn);
	    } 
	    catch (IllegalArgumentException e) 
	    {
	      // Means we weren't bound, which is ok.
	    }
	    setBoundService(null);
	  }
}